home *** CD-ROM | disk | FTP | other *** search
/ Trading on the Edge / Trading On The Edge - CD-ROM Toolkit (Wayzata Technology)(2031)(1994).bin / pc / mac_file / software / nn_prepr / findic.c < prev    next >
C/C++ Source or Header  |  1992-08-25  |  13KB  |  420 lines

  1. /* 11:58 15-Aug-92  (findic.c)  Dictionary Management for Financial Rtnes */
  2.  
  3. #include "fin.h"
  4.  
  5. /************************************************************************
  6.  * Copyright(C) 1992 High-Tech Communications.                          *
  7.  * 103 Buckskin Court, Sewickley, PA 15143                              *
  8.  *                                                                      *
  9.  * Written by Casimir C. Klimasauskas                                   *
  10.  *                                                                      *
  11.  * All rights reserved.  No part of this program may be reproduced,     *
  12.  * stored in a retrieval system, or tramsmitted, in any form or by any  *
  13.  * means, electronic, mechanical, photocopying, recording or otherwise  *
  14.  * without the prior written permission of the copyright owner,         *
  15.  * High-Tech Communications.                                            *
  16.  *                                                                      *
  17.  * These programs are supplied on an "as-is" basis with no warranties   *
  18.  * of fitness or operability, either express or implied.                *
  19.  *                                                                      *
  20.  ************************************************************************
  21.  */
  22.  
  23. /************************************************************************
  24.  *                                    *
  25.  *        Dictionary Routines for Storing "strings"        *
  26.  *                                    *
  27.  ************************************************************************
  28.     Date2BinL( cp )    - convert a date to long
  29.     Date2StrCP( l )    - convert a long to a date
  30.     DCFreeV( )        - free the dictionary
  31.     DCInitV( size )    - initialize the dictionary
  32.     DCLwrPkCP( cp )    - convert to lower case & pack characters
  33.     DCDupCP(  cp )    - find or allocate a string
  34.  */
  35.  
  36. typedef struct _dict {        /* dictionary entry */
  37.     struct _dict    *DNextP;    /* next item in chain */
  38.     char         DStr[1];    /* string itself */
  39. } DICT;
  40.  
  41. char    *DictBlkCP    = {0};    /* dictionary block */
  42. long     DictSizeL    = {0};    /* size of dictionary */
  43. long     DictCurXL    = {0};    /* current index into dictionary */
  44. DICT    *DictHash[128]    = {0};    /* hash table for string */
  45.  
  46. /************************************************************************
  47.  *                                    *
  48.  *    Asc2NumD() - convert an ascii string to a number        *
  49.  *                                    *
  50.  ************************************************************************
  51.    This routine is designed to handle a variety of number data types:
  52.     [+|-]nnn[,]nnn.nn        - floating point number
  53.     [+|-]n[,]nnn nnn/nnn        - quote
  54.  
  55.    It tries to classify the number type by counting the number of "/"'s in
  56.    the string.  It then performs the proper de-composition to handle the
  57.    number.
  58. */
  59.  
  60. double Asc2NumD( iCP, nc )    /* convert ascii string to a number */
  61. char        *iCP;        /* string pointer */
  62. int         nc;        /* # of characters (max) in string */
  63. {
  64.     int         wxI;        /* work index */
  65.     int         nslash;    /* # of slashes */
  66.  
  67.     char    *sp, *dp;    /* work string pointers */
  68.     char    *lnbp;        /* last non-blank character */
  69.     int         exp;        /* exponent */
  70.     double     rv;        /* return value */
  71.     double     num;        /* numerator */
  72.     double     den;        /* denominator */
  73.     int         fracf;        /* fraction flag */
  74.     int         c;        /* work char */
  75.     int         sign=0;    /* sign of the answer */
  76.  
  77.     char     sbf[40];    /* work buffer */
  78.  
  79.     dp     = (char *)0;        /* null until first non-blank char */
  80.     nslash = 0;            /* # of slashes */
  81.     lnbp   = (char *)0;
  82.     for( sp=iCP,wxI=nc; (c = *sp)!=0 && wxI>0; sp++,wxI-- ) {
  83.     if ( c == '/' ) nslash++;
  84.     if ( c > ' ' && dp == (char *)0 ) dp = &sbf[0];
  85.     if ( 'A' <= c && c <= 'Z' ) c -= 'A'-'a';
  86.     if ( dp ) *dp++ = c;
  87.     if ( c > ' ' ) lnbp = dp;
  88.     }
  89.     if ( dp == (char *)0 ) goto BadNumber;
  90.     *dp = 0;                /* null terminate */
  91.     if ( lnbp != (char *)0 ) *lnbp = 0;    /* truncate trailing spaces */
  92.  
  93.     /* --- Check for special numbers --- */
  94.  
  95.     if ( strcmp( sbf, "na"  ) == 0 ||
  96.      strcmp( sbf, "hol" ) == 0 ||
  97.      strcmp( sbf, "nd"  ) == 0 ||
  98.      strcmp( sbf, "n/a" ) == 0 ) {
  99.     rv = 0.0;
  100.     goto GoodNumber;
  101.     }
  102.  
  103.     /* translate the number */
  104.     exp   = -1;
  105.     rv    = 0.0;
  106.     num   = 0.0;
  107.     den   = 0.0;
  108.     fracf = 0;
  109.     sp      = &sbf[0];
  110.     if ( (c = *sp) == '+' )    sign =  1, sp++;
  111.     else if ( c == '-' )    sign = -1, sp++;
  112.  
  113.     for( c = *sp; ('0'<=c && c<='9') || c=='.' || c==','; c = *sp ) {
  114.     sp++;
  115.     if ( c == ',' ) continue;    /* ignore commas */
  116.     if ( c == '.' ) {
  117.         if ( exp >= 0 ) {
  118.         fprintf( stderr, "illegal number <%s>: multiple decimals\n",
  119.             sbf );
  120.         goto BadNumber;
  121.         }
  122.         exp = 0;
  123.         continue;
  124.     }
  125.  
  126.     rv = rv * 10. + (c - '0');
  127.     if ( exp >= 0 ) exp++;
  128.     }
  129.  
  130.     /* account for fractional part of the number */
  131.     for(; exp >= 3; exp -= 3 )    rv *= .001;
  132.     for(; exp >  0; exp--    )    rv *= .1;
  133.  
  134.     /* if there is a fraction, convert it too */
  135.     if ( nslash == 0 ) goto GoodNumber;
  136.  
  137.     /* convert the fraction */
  138.     while( *sp == ' ' ) sp++;
  139.     for( c = *sp; '0' <= c && c <= '9'; c = *sp ) {
  140.     sp++;
  141.     num = (10. * num) + (c - '0');
  142.     }
  143.     if ( c != '/' ) {
  144.     fprintf( stderr, "illegal format number <%s>: missing /\n", sbf );
  145.     goto BadNumber;
  146.     }
  147.     for( c = *++sp; '0' <= c && c <= '9'; c = *sp ) {
  148.     sp++;
  149.     den = (10. * den) + (c - '0');
  150.     }
  151.     if ( den != 0.0 ) rv += num / den;    /* merge fraction with whole part */
  152.  
  153. GoodNumber:
  154.     if ( *sp != 0 ) {
  155.     fprintf( stderr, "illegal number format: embedded spaces <%s>\n", sbf );
  156.     }
  157.     if ( sign < 0 && rv != 0.0 ) rv = 0 - rv;
  158.     return( rv );
  159.  
  160. BadNumber:
  161.     return( 0.0 );
  162. }
  163.  
  164. /* --- Date2BinL() --- 
  165.  *    Convert a date to a binary number: packed decimal  yyyymmdd
  166.  *    formats accepted:  mm/dd/yy, mm-dd-yy, dd-mmm-yy
  167.  */
  168.  
  169. long Date2BinL( dCP )    /* convert a date to binary */
  170. char        *dCP;    /* date string pointer */
  171. {
  172.     int         d,m,y;    /* day, month, year */
  173.     long     dL;    /* resulting date */
  174.     register char *sp;    /* work string pointer */
  175.     char    *ap;    /* alternate pointer */
  176.     int         nasc;    /* # of ascii characters */
  177.     int         ndig;    /* # of digits */
  178.     int         noth;    /* # of other characters */
  179.     int         ndash;    /* # of dashes */
  180.     int         nslash; /* # of slashes */
  181.     char     MosCA[] = {"janfebmaraprmayjunjulaugsepoctnovdec"};
  182.  
  183.     if ( dCP == (char *)0 ) goto BadDate;
  184.     for( sp = dCP; *sp && *sp <= ' '; ) sp++;
  185.     if ( *sp == 0 ) goto BadDate;
  186.  
  187.     nasc = ndig = noth = ndash = nslash = 0;
  188.     for( ap = sp; *ap > ' '; ap++ ) {
  189.     if ( *ap == '/' || *ap == '\\' )    nslash++;
  190.     else if ( *ap == '-' )            ndash++;
  191.     else if ( '0' <= *ap && *ap <= '9' )    ndig++;
  192.     else if ( 'a' <= *ap && *ap <= 'z' )    nasc++;
  193.     else if ( 'A' <= *ap && *ap <= 'Z' ) {    nasc++;
  194.         *ap -= 'A' -'a';
  195.     } else                    noth++;
  196.     }
  197.  
  198.     if ( noth != 0 ) goto BadDate;    /* bad date */
  199.  
  200.     if ( nasc == 3 && ndash == 2 && ndig > 2 ) {
  201.     /* must be dd-mmm-yy format */
  202.     for( d = 0; '0' <= *sp && *sp <= '9'; sp++ )
  203.         d = (d<<4) | (*sp & 0xf);
  204.  
  205.     if ( *sp != '/' && *sp != '\\' && *sp != '-' )
  206.         goto BadDate;
  207.     sp++;
  208.  
  209.     for( m = 0; m < 12; m++ )
  210.         if ( strncmp( &MosCA[3*m], sp, 3 ) == 0 ) break;
  211.     if ( m >= 12 ) goto BadDate;
  212.     m = (m%10) | ((m/10)<<4);
  213.     sp += 3;
  214.  
  215.     if ( *sp != '/' && *sp != '\\' && *sp != '-' )
  216.         goto BadDate;
  217.     sp++;
  218.  
  219.     for( y = 0; '0' <= *sp && *sp <= '9'; sp++ )
  220.         y = (y<<4) | (*sp & 0xf);
  221.     if ( y < 0x100 ) y += 0x1900;
  222.  
  223.     } else if ( nasc == 0 && ndig > 2 ) {
  224.     /* must be mm/dd/yy or mm-dd-yy format */
  225.  
  226.     for( m = 0; '0' <= *sp && *sp <= '9'; sp++ )
  227.         m = (m << 4) | (*sp & 0xf);
  228.  
  229.     if ( *sp != '/' && *sp != '\\' && *sp != '-' )
  230.         goto BadDate;
  231.     sp++;
  232.  
  233.     for( d = 0; '0' <= *sp && *sp <= '9'; sp++ )
  234.         d = (d << 4) | (*sp & 0xf);
  235.  
  236.     if ( *sp != '/' && *sp != '\\' && *sp != '-' )
  237.         goto BadDate;
  238.     sp++;
  239.  
  240.     for( y = 0; '0' <= *sp && *sp <= '9'; sp++ )
  241.         y = (y << 4) | (*sp & 0xf);
  242.     if ( y < 0x100 ) y += 0x1900;
  243.  
  244.     } else goto BadDate;            /* bad date format */
  245.  
  246.     dL = (((long)y & 0x7fffL) << 16) | ((m & 0xff) << 8) | (d & 0xff);
  247. Done:
  248. #ifdef TEST1
  249.     printf( "Date2BinL: dCP=<%s> dL=%08lx\n", dCP, dL );
  250.     fflush( stdout );
  251. #endif
  252.     return( dL );
  253. BadDate:
  254.     dL = -1L;
  255.     goto Done;
  256. }
  257.  
  258. /* --- Date2StrCP() ---
  259.  *    Convert an internal format yyyymmdd date to a string:  mm/dd/yy
  260.  */
  261.  
  262. char *Date2StrCP( dateL )
  263. long        dateL;        /* date as a long */
  264. {
  265.     char    *dp;        /* destination pointer */
  266.     static char    dCA[10] = {0};
  267.  
  268.     dp = &dCA[0];
  269.     *dp++ = (int)(((dateL >> 12) & 0xf) | '0');
  270.     *dp++ = (int)(((dateL >>  8) & 0xf) | '0');
  271.     *dp++ = '/';
  272.     *dp++ = (int)(((dateL >>  4) & 0xf) | '0');
  273.     *dp++ = (int)(((dateL      ) & 0xf) | '0');
  274.     *dp++ = '/';
  275.     *dp++ = (int)(((dateL >> 20) & 0xf) | '0');
  276.     *dp++ = (int)(((dateL >> 16) & 0xf) | '0');
  277.     *dp++ = 0;
  278. #ifdef TEST1
  279.     printf( "Date2StrCP: dateL=%08lx str=<%s>\n", dateL, dCA );
  280.     fflush( stdout );
  281. #endif
  282.     return( (char *)&dCA[0] );
  283. }
  284.  
  285. /* --- DCClearV ---
  286.  *    Clear the dictionary of everything.  Do not release memory.
  287.  */
  288.  
  289. void DCClearV()
  290. {
  291.     int         i;        /* work index */
  292.  
  293.     DictCurXL = 0;
  294.     for( i = 0; i < sizeof(DictHash)/sizeof(DictHash[0]); i++ )
  295.     DictHash[i] = (DICT *)0;
  296. }
  297.  
  298.  
  299. /* --- DCFreeV ---
  300.  *    Free Memory in the dictionary
  301.  */
  302.  
  303. void DCFreeV()        /* free dicitonary */
  304. {
  305.     int         i;        /* work index */
  306.  
  307.     DCClearV();            /* clear out hash tables */
  308.  
  309.     if ( DictBlkCP != (char *)0 ) free( (void *)DictBlkCP );
  310.     DictBlkCP = (char *)0;
  311.     DictSizeL = 0;
  312. #ifdef TEST1
  313.     printf( "DCFreeV: done\n" );
  314.     fflush( stdout );
  315. #endif
  316.     return;
  317. }
  318.  
  319. /* --- DCInitV ---
  320.  *    Allocate memory for dictionary.  If memory already allocated,
  321.  *    Free that memory.  Reset all tables when done.
  322.  */
  323.  
  324. void DCInitV( sizeL )        /* initialize the dictionary */
  325. long         sizeL;        /* size to make (max 64K) */
  326. {
  327.     char    *wCP;        /* work char pointer */
  328.  
  329.     if ( sizeL <= 0 )       sizeL = 0x4000L;    /* 16K */
  330.     if ( sizeL > 0xfff0L ) sizeL = 0xfff0L;    /* max 64K */
  331.     if ( (wCP = malloc( (unsigned)sizeL )) == (char *)0 ) {
  332.     fprintf( stderr, "insufficient memory for dictionary (%ld)\n", sizeL );
  333.     exit( 2 );
  334.     }
  335.     DCFreeV();
  336.     DictBlkCP = (char *)wCP;
  337.     DictSizeL = sizeL;
  338. #ifdef TEST1
  339.     printf( "DCInitV: sizeL=%08ld DictBlkCP=%08lx\n", sizeL, DictBlkCP );
  340.     fflush( stdout );
  341. #endif
  342.     return;
  343. }
  344.  
  345. /* --- DCLwrPkCP ---
  346.  *    Convert to lower case & pack characters.
  347.  *    Kill blanks & whitespace.
  348.  */
  349.  
  350. char *DCLwrPkCP( sp )    /* convert to lower case & pack characters */
  351. char    *sp;        /* string to pack in place */
  352. {
  353.     char    *sp0;    /* return string */
  354.     char    *dp;    /* destination pointer */
  355.     int         c;    /* character */
  356.  
  357. #ifdef TEST1
  358.     printf( "DCLwrPkCP: sp=<%s>", sp );
  359.     fflush( stdout );
  360. #endif
  361.     for( dp = sp0 = sp; (c = *sp & 0x7f) != 0; sp++ ) {
  362.     if ( 'A' <= c && c <= 'Z' ) c -= 'A' - 'a';
  363.     if ( c > ' ' ) *dp++ = c;
  364.     }
  365.     *dp = 0;
  366. #ifdef TEST1
  367.     printf( " sp0=<%s>\n", sp0 );
  368.     fflush( stdout );
  369. #endif
  370.     return( sp0 );
  371. }
  372.  
  373. /* --- DCDupCP ---
  374.  *    Find or duplicate a string.  Use the first character as a
  375.  *    "hash" value.
  376.  */
  377.  
  378. char *DCDupCP( sp )    /* find / duplicate a string */
  379. char    *sp;        /* string to find / duplicate */
  380. {
  381.     DICT    *wDP;    /* work dictionary pointer */
  382.     DICT    *pDP;    /* previous dictionary pointer */
  383.     int         wx;    /* starting index */
  384.  
  385.     if ( DictBlkCP == (char *)0 || DictSizeL == 0 )
  386.     DCInitV( 0L );            /* default initialization */
  387.  
  388.     wx = *sp & 0x7f;            /* hash index */
  389.     pDP = (DICT *)&DictHash[wx];    /* point to hash table */
  390.     while( (wDP = pDP->DNextP) != (DICT *)0 ) {
  391.     wx = strcmp( wDP->DStr, sp );
  392.     if ( wx == 0 )
  393.         return( &wDP->DStr[0] );    /* found the string */
  394.     if ( wx > 0 ) break;        /* past the string */
  395.     pDP = wDP;            /* link forward */
  396.     }
  397.  
  398.     /* --- string was not found:  add it --- */
  399.     wx = ((strlen(sp) + 4) & (-4)) + sizeof(DICT *);
  400.     if ( (wx + DictCurXL) > DictSizeL ) {
  401.     fprintf( stderr, "Dictionary full for <%s>!\n", sp );
  402.     exit( 3 );
  403.     }
  404.  
  405.     wDP = (DICT *)(DictBlkCP + DictCurXL);
  406.     wDP->DNextP = pDP->DNextP;        /* insert the new item in chain */
  407.     pDP->DNextP = wDP;
  408.     strcpy( &wDP->DStr[0], sp );    /* copy the string to dictionary */
  409.     DictCurXL += wx;            /* update next free space */
  410. #ifdef TEST1
  411.     printf( "DCDupCP: s=<%s> hx=%d p=%08lx wx=%d\n", 
  412.     sp, *sp&0x7f, DictHash[*sp&0x7f], wx );
  413.     printf( "         wDP=%08lx->%08lx pDP=%08lx->%08lx DictCurXL=%ld\n",
  414.     wDP, wDP->DNextP, pDP, pDP->DNextP, DictCurXL );
  415.     fflush( stdout );
  416. #endif
  417.     return( &wDP->DStr[0] );
  418. }
  419.  
  420.